package com.sweet.multipledatasources.db;

import com.zaxxer.hikari.HikariDataSource;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.jdbcclient.JDBCPool;
import io.vertx.sqlclient.*;


public class DbVerticle extends AbstractVerticle {
  private final Logger logger = LoggerFactory.getLogger(DbVerticle.class);

  public static void main(String[] args) {
    Vertx.vertx().deployVerticle(new DbVerticle());
  }

  @Override
  public void start() throws Exception {
    logger.debug("configDb: " + config().toString());
    Boolean use = config().getBoolean("use", true);
    if (!use) {
      logger.debug(config().getString("name") + " -> use:" + use);
      return;
    }
    String dbName = config().getString("name");
    logger.debug("["+ dbName + "]initPool...");
    JDBCPool pool = initPool(config());
    logger.debug("registerEventBus:" + dbName);
    vertx.eventBus().<JsonObject>localConsumer(dbName, msg -> {
      JsonObject body = msg.body();
      logger.debug("[" + dbName + "]EventBusMsg: " + body);
      JsonArray param = body.getJsonArray("param");
      String sql = body.getString("sql");
      pool.preparedQuery(sql).execute(Tuple.from(param.getList()))
              .onFailure(fail -> {
                logger.error("[" + dbName + "]queryErr:" + sql + ", params: " + param);
                msg.fail(-1, dbName + ":" + fail.getMessage());
              }).onSuccess(res -> {
                JsonArray array = rowSetToJsonArray(res);
                msg.reply(new JsonObject().put("dbName", dbName).put("list", array));
              });
    });
  }

  private JsonArray rowSetToJsonArray(RowSet<Row> res) {
    JsonArray array = new JsonArray();
    for (Row re : res) {
      array.add(re.toJson());
    }
    return array;
  }

  @Override
  public void stop() throws Exception {
    logger.debug("dbServiceStop");
    super.stop();
  }

  private JDBCPool initPool(JsonObject object) {
    HikariDataSource dataSource = new HikariDataSource();
    String driverClassName = object.getString("driverClassName", "com.mysql.cj.jdbc.Driver");
    dataSource.setDriverClassName(driverClassName);
    dataSource.setJdbcUrl(object.getString("jdbcUrl"));
    dataSource.setUsername(object.getString("userName"));
    dataSource.setPassword(object.getString("password"));
    dataSource.setMaximumPoolSize(object.getInteger("maxPoolSize", 10));
    dataSource.setMaxLifetime(object.getLong("maxLifetime", 1765000L));
//    if (driverClassName.contains("oracle")) {
//      dataSource.addDataSourceProperty("currentSchema", "SYSTEM");
//    }
    return JDBCPool.pool(vertx, dataSource);
  }
}
